<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<html lang="zh-CN"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta http-equiv="Content-Language" content="zh-CN"><link href="stylesheet.css" media="all" rel="stylesheet" type="text/css">
<title>数据库访问</title>
<script> var _hmt = _hmt || []; (function() { var hm = document.createElement("script"); hm.src = "https://hm.baidu.com/hm.js?d286c55b63a3c54a1e43d10d4c203e75"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })(); </script>
</head><body class="SECT1">
<div>
<table summary="Header navigation table" width="100%" border="0" cellpadding="0" cellspacing="0">
<tr><th colspan="5" align="center" valign="bottom">PostgreSQL 8.2.3 中文文档</th></tr>
<tr><td width="10%" align="left" valign="top"><a href="plpython-trigger.html" accesskey="P">后退</a></td><td width="10%" align="left" valign="top"><a href="plpython.html">快退</a></td><td width="60%" align="center" valign="bottom">章40. PL/Python - Python 过程语言</td><td width="10%" align="right" valign="top"><a href="plpython.html">快进</a></td><td width="10%" align="right" valign="top"><a href="spi.html" accesskey="N">前进</a></td></tr>
</table>
<hr align="LEFT" width="100%"></div>
<div class="SECT1"><h1 class="SECT1"><a name="PLPYTHON-DATABASE">40.3. 数据库访问</a></h1>
<p>PL/Python 语言模块自动输入一个叫 <tt class="LITERAL">plpy</tt> 的 Python 模块。在这个模块里的函数和常量可以在 Python 代码里以 <tt class="LITERAL">plpy.<tt class="REPLACEABLE"><i>foo</i></tt></tt> 的名字获得。目前，<tt class="LITERAL">plpy</tt> 实现了函数 <tt class="LITERAL">plpy.debug(<tt class="REPLACEABLE"><i>msg</i></tt>)</tt>, <tt class="LITERAL">plpy.log(<tt class="REPLACEABLE"><i>msg</i></tt>)</tt>, <tt class="LITERAL">plpy.info(<tt class="REPLACEABLE"><i>msg</i></tt>)</tt>, <tt class="LITERAL">plpy.notice(<tt class="REPLACEABLE"><i>msg</i></tt>)</tt>, <tt class="LITERAL">plpy.warning(<tt class="REPLACEABLE"><i>msg</i></tt>)</tt>, <tt class="LITERAL">plpy.error(<tt class="REPLACEABLE"><i>msg</i></tt>)</tt>, <tt class="LITERAL">plpy.fatal(<tt class="REPLACEABLE"><i>msg</i></tt>)</tt> 。<code class="FUNCTION">plpy.error</code> 和 <code class="FUNCTION">plpy.fatal</code> 实际上抛出一个 Python 异常，如果你没有捕获这个异常，则会传播到调用的查询，导致当前事务或者子事务退出。<tt class="LITERAL">raise plpy.ERROR(<tt class="REPLACEABLE"><i>msg</i></tt>)</tt> 和 <tt class="LITERAL">raise plpy.FATAL(<tt class="REPLACEABLE"><i>msg</i></tt>)</tt> 分别等效于调用 <code class="FUNCTION">plpy.error</code> 和 <code class="FUNCTION">plpy.fatal</code> 。其它函数只生成不同优先级的信息。特定优先级的信息是汇报给客户端、写到服务器日志、还是两件事都做，是由 <a href="runtime-config-logging.html#GUC-LOG-MIN-MESSAGES">log_min_messages</a> 和 <a href="runtime-config-logging.html#GUC-CLIENT-MIN-MESSAGES">client_min_messages</a> 配置参数控制的。参阅<a href="runtime-config.html">章17</a>获取更多信息。</p>
<p>另外，<tt class="LITERAL">plpy</tt> 模块提供两个函数，叫 <code class="FUNCTION">execute</code> 和 <code class="FUNCTION">prepare</code> 。拿一个查询字符串和一个可选的限制参数调用 <code class="FUNCTION">plpy.execute</code> 可以运行该查询，并且结果返回到一个结果对象里。结果对象仿真一个列表或者一个字典对象。结果对象可以通过行号和字段名来访问。它有下面这些额外的方法：<code class="FUNCTION">nrows</code> 返回该查询返回的行数，而 <code class="FUNCTION">status</code> 是 <code class="FUNCTION">SPI_execute()</code> 的返回变量。结果对象可能被修改。</p>
<p>比如：</p>
<pre class="PROGRAMLISTING">rv = plpy.execute("SELECT * FROM my_table", 5)</pre>
<p>返回来自 <tt class="LITERAL">my_table</tt> 中最多 5 行。如果 <tt class="LITERAL">my_table</tt> 有一个 <tt class="LITERAL">my_column</tt> 字段，那么你可以用下面的方法访问它</p>
<pre class="PROGRAMLISTING">foo = rv[i]["my_column"]</pre>
<p>第二个函数，<code class="FUNCTION">plpy.prepare</code> ，为一个查询准备查询规划。它是带一个查询字符串和一个参数类型列表(如果你在该查询里有引用变量)调用的，比如：</p>
<pre class="PROGRAMLISTING">plan = plpy.prepare("SELECT last_name FROM my_users WHERE first_name = $1", [ "text" ])</pre>
<p><tt class="LITERAL">text</tt> 是你将作为 <tt class="LITERAL">$1</tt> 传递的变量的类型。在准备一个语句之后，你用函数 <code class="FUNCTION">plpy.execute</code> 运行它。</p>
<pre class="PROGRAMLISTING">rv = plpy.execute(plan, [ "name" ], 5)</pre>
<p>第三个参数是限制，是可选的。</p>
<p>在你用 PL/Python 模块准备一个计划的时候，该计划是自动保存的。请阅读 SPI 文档(<a href="spi.html">章41</a>)获取这句话的含义。为了能跨函数调用有效地使用这个特点，需要使用永久存储字典 <tt class="LITERAL">SD</tt> 或 <tt class="LITERAL">GD</tt> 之一(参阅<a href="plpython-funcs.html">节40.1</a>)。比如：</p>
<pre class="PROGRAMLISTING">CREATE FUNCTION usesavedplan() RETURNS trigger AS $$
    if SD.has_key("plan"):
        plan = SD["plan"]
    else:
        plan = plpy.prepare("SELECT 1")
        SD["plan"] = plan
    # 函数结果
$$ LANGUAGE plpythonu;</pre>
</div>
<div>
<hr align="LEFT" width="100%">
<table summary="Footer navigation table" width="100%" border="0" cellpadding="0" cellspacing="0">
<tr><td width="33%" align="left" valign="top"><a href="plpython-trigger.html" accesskey="P">后退</a></td><td width="34%" align="center" valign="top"><a href="index.html" accesskey="H">首页</a></td><td width="33%" align="right" valign="top"><a href="spi.html" accesskey="N">前进</a></td></tr>
<tr><td width="33%" align="left" valign="top">触发器函数</td><td width="34%" align="center" valign="top"><a href="plpython.html" accesskey="U">上一级</a></td><td width="33%" align="right" valign="top">服务器编程接口</td></tr>
</table>
</div>
</body></html>